#pragma once

#include "Core.h"

#ifdef _WIN32
namespace Gut
{
	struct ShaderStorageBuffer
	{
		unsigned int SSBO;
		struct Desc
		{
			const void *data = 0;
			unsigned int dataLen;
			unsigned int usage = GL_DYNAMIC_COPY;
			unsigned int binding;
		};

		bool Create(const Desc &desc);

		template <typename T>
		bool Create(unsigned int binding)
		{
			Desc desc;
			desc.dataLen = sizeof(T);
			desc.binding = binding;
			return Create(desc);
		}

		template <typename T>
		void Write(const T &buf)
		{
			glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO);
			GLvoid *p = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
			memcpy(p, &buf, sizeof(buf));
			glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
		};

		template <typename T>
		void Write(void *data, int len)
		{
			glBindBuffer(GL_SHADER_STORAGE_BUFFER, SSBO);
			GLvoid *p = glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_WRITE_ONLY);
			memcpy(p, data, len);
			glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
		}

		template <typename T>
		void Read(T &t)
		{
			Read(&t, sizeof(T));
		}
		void Read(void *data, int dataLen);
		void Delete();
	};

}
#endif
